package com.learning.dynamic.executor.monitor;

import com.learning.dynamic.executor.executor.DynamicExecutor;
import com.learning.dynamic.executor.utils.SpringBeanUtil;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;

import java.util.Date;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * @author Wang Xu
 * @date 2023/11/7
 */
public class DynamicExecutorMonitor implements ApplicationRunner {
    private static final Logger LOGGER = LoggerFactory.getLogger(DynamicExecutorMonitor.class);
    private static final ScheduledExecutorService SCHEDULED_EXECUTOR = Executors.newSingleThreadScheduledExecutor();


    /**
     * 做线程池指标监控，这里可以做成数据上报之类的集成
     */
    public void monitor() {
        SpringBeanUtil.getAllBean(DynamicExecutor.class).forEach(nb -> {
            String poolName = nb.getBeanName();
            LOGGER.info("\npoolName [{}] 当前指标监控如下：" +
                    "\nPoolSize is : {}" +
                    "\nCorePoolSize is : {}" +
                    "\nMaximumPoolSize is : {}" +
                    "\nActiveCount is : {}" +
                    "\nTaskCount is : {}" +
                    "\n时间：{}\n\n",
                    poolName,
                    nb.getBean().getPoolSize(),
                    nb.getBean().getCorePoolSize(),
                    nb.getBean().getMaximumPoolSize(),
                    nb.getBean().getActiveCount(),
                    nb.getBean().getTaskCount(),
                    DateFormatUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss"));
        });
    }

    /**
     * 这里可以做一些告警机制
     */
    public void alarm() {
        LOGGER.info("alarm . . .");
    }

    @Override
    public void run(ApplicationArguments args) throws Exception {
        SCHEDULED_EXECUTOR.scheduleAtFixedRate(() -> {
            try {
                monitor();
                alarm();
            } catch (Exception e) {
                LOGGER.error("SCHEDULED_EXECUTOR.scheduleAtFixedRate exec failed : ", e);
            }
            LOGGER.info("SCHEDULED_EXECUTOR.scheduleAtFixedRate 执行中...");
        }, 0, 5, TimeUnit.SECONDS);
        LOGGER.info("SCHEDULED_EXECUTOR.scheduleAtFixedRate 准备执行...");
    }
}